package cn.ellacat.tools.fixvhdwr;

import java.io.*;

/**
 * @author wjc133
 */
public class VhdWriter {
    /**
     * 写入数据到VHD文件
     *
     * @param rawFilePath 原始二进制数据文件路径(由nasm生成的二进制文件)
     * @param vhdFilePath VHD文件的路径。如果路径为空，默认使用user目录下生成raw.vhd，若路径不存在，则创建
     * @param maxSector   最大写入扇区数，0为不限制
     */
    public void write(String rawFilePath, String vhdFilePath, int maxSector) throws IOException {
        File rawFile = getRawFile(rawFilePath);
        System.out.println("Write start, rawFile is " + rawFile.length() + " bytes.");
        File vhdFile = getVhdFile(vhdFilePath);
        byte[] rawData = getRawData(rawFile, maxSector);
        writeRawData2Vhd(rawData, vhdFile);
        Footer footer = buildFooter(rawFile);
        writeFooter2Vhd(footer, vhdFile);
        System.out.println("Write finish, vhdFile is " + vhdFile.length() + " bytes.");
    }

    private Footer buildFooter(File rawFile) {
        Footer footer = new Footer();
        long size = rawFile.length();
        footer.setCurrSize(size);
        footer.setOrigSize(size);
        return footer;
    }

    private void writeRawData2Vhd(byte[] rawData, File vhdFile) throws IOException {
        FileOutputStream stream = new FileOutputStream(vhdFile);
        stream.write(rawData);
        stream.flush();
        stream.close();
    }

    private File getVhdFile(String vhdFilePath) throws IOException {
        if (vhdFilePath == null) {
            String home = System.getProperty("user.home");
            if (home == null || "".equals(home) || home.length() == 0) {
                throw new IllegalArgumentException("illegal argument about vhdFilePath, and user home is not available");
            }
            File file = new File(home + "/raw.vhd");
            return createNewFile(file);
        }
        File file = new File(vhdFilePath);
        if (!file.exists()) {
            return createNewFile(file);
        }
        return file;
    }

    private File createNewFile(File file) throws IOException {
        boolean success = file.createNewFile();
        if (!success) {
            throw new IllegalArgumentException("权限不足");
        }
        return file;
    }

    private byte[] getRawData(File rawFile, int maxSector) throws IOException {
        byte[] buffer = new byte[maxSector * 512];
        FileInputStream input = new FileInputStream(rawFile);
        input.read(buffer);
        input.close();
        return buffer;
    }

    private File getRawFile(String rawFilePath) throws FileNotFoundException {
        File file = new File(rawFilePath);
        if (!file.exists()) {
            throw new FileNotFoundException("raw file is not exist");
        }
        return file;
    }

    private void writeFooter2Vhd(Footer footer, File vhdFile) throws IOException {
        long length = vhdFile.length();
        int sections = (int) (length % 512 == 0 ? length / 512 : length / 512 + 1);
        byte[] footerBytes = footer.toBytes(sections);
        FileOutputStream stream = new FileOutputStream(vhdFile, true);
        stream.write(footerBytes);
        stream.flush();
        stream.close();
    }
}
